#pragma once
// #autor:yxj
#include "rclcpp/rclcpp.hpp"
#include <agv_peripheral_controller/roller/io_lift.h>
#include <agv_msgs/msg/read_in_puts_new_sim.hpp>
/////////////////////输入IO////////////////////////
#define RESET_BTN "resetButton"
// 开关信号
// 光通讯信号-输入io
// oc: Optical communication
#define OC_DATA_TRANSMISSION "ocDataTransmission"
#define OC_LIGHT_STABLE "oclightStable" // 暂不启用
// 光通讯模块四路输入
#define OC_INPUT1 "ocInput1"
#define OC_INPUT2 "ocInput2"
#define OC_INPUT3 "ocInput3"
#define OC_INPUT4 "ocInput4"

// 辊筒物料检测1-4
#define CARGO_INPUT1 "cargoInput1"
#define CARGO_INPUT2 "cargoInput2"
#define CARGO_INPUT3 "cargoInput3"
#define CARGO_INPUT4 "cargoInput4"

// 辊筒正反转旋钮
#define SWITCH_FORWARD_ROLLER "switchForwardRoller"
#define SWITCH_REVERSE_ROLLER "switchReverseRoller"

////////////////////////输出IO///////////////////////////////
// 辊筒电源-控制输出io
#define POWER_ROLLER "powerRoller"

// 光通讯模块四路输出
#define OC_OUTPUT1 "ocOutput1"
#define OC_OUTPUT2 "ocOutput2"
#define OC_OUTPUT3 "ocOutput3"
#define OC_OUTPUT4 "ocOutput4"

////////////////////////////HMI虚拟输入/////////////////////////////////////
// HMI控制虚拟按钮
#define HMI_PICK "hmi_pick"
#define HMI_DROP "hmi_drop"
#define HMI_PAUSE "hmi_pause"
#define HMI_FINISH "hmi_finish"

// HMI控制关通信输出
#define HMI_OC_OUT1 "hmi_ocOutput1"
#define HMI_OC_OUT2 "hmi_ocOutput2"
#define HMI_OC_OUT3 "hmi_ocOutput3"
#define HMI_OC_OUT4 "hmi_ocOutput4"
///////////////////////阻挡举升机构控制组///////////////////////////////
namespace peripheral_roller
{

    enum class HmiSig
    {
        pick = 0,   // 一键取货
        drop = 1,   // 一键卸货
        pause = 2,  // 结束一键取送货
        finish = 3, // 提前结束
        ocOu1 = 4,  // 光通信1~4
        ocOu2 = 5,
        ocOu3 = 6,
        ocOu4 = 7

    };

    // IO举升控制类
    class CRollerSignal
    {
    public:
        // 默认构造函数
        CRollerSignal();

        // 析构函数
        ~CRollerSignal();

        // 初始化函数
        bool init();

        // 货物装填
        bool loadStatus();

        // 手动旋钮状态
        SwitchState switchBtn();

        // 货物检测数据合并bits低到高
        uint64_t cargoInputBits(bool positive);

        // 货物输入的数量
        std::size_t cargoInputSize();

        // 检测某一路货物输入是否触发
        bool cargoInput(std::size_t index);

        // 检测光通信输入通道某一路是否触发
        bool ocInput(std::size_t index);

        // 单独设置某一路光通讯输出
        bool ocOutput(std::size_t index, bool level);

        // 辊筒电机驱动器电源设置
        bool powerSet(bool level);

        // 光通讯数据通信正常且信号处于复位状态
        bool ocInputNormal();

        // 光通讯输出信号复位
        bool ocOutputReset();

        // 光通讯模式是否正常
        bool ocDataT();

        // 复位按钮是否按下
        bool resetBtnPressed();

        // 获取虚拟hmi io
        bool getHmi(HmiSig index);
        
        //  输出仿真oc out信号
        bool simOcOutCycle();

    private:
        // 获取新IO输入信号回调函数
        void readInputNewCallBack(const agv_msgs::msg::ReadInPutsNew &msg);

        //  获取仿真新IO输入信号回调函数-来自HMI触发
        void readInputNewSimCallBack(const agv_msgs::msg::ReadInPutsNewSim &msg);

        // 更新输入IO对象
        void updateInutIoNew(const agv_msgs::msg::ReadInPutsNew &msg, INPUT_IO_TYPE &inputIoObj);

        // 是否初始化完成
        bool initFinish();

    private:
        // DT-光通讯模块数据正常信号
        INPUT_IO_TYPE m_ocDataT;

        // 光通讯模块多路输入信号
        std::vector<INPUT_IO_TYPE> m_ocInputs;

        // 光通讯模块多路输出信号
        IO_GROUP m_ocOutputs;

        // 货物检测多路输入信号
        std::vector<INPUT_IO_TYPE> m_cargoInputs;

        // 控制io输出工具类
        COutputIoTool m_outputIoTool;

        // 手动正转旋钮信号触发
        INPUT_IO_TYPE m_forwardSwitch;

        // 手动反转旋钮信号触发
        INPUT_IO_TYPE m_reverseSwitch;

        // 辊筒电机电源输出信号
        OUTPUT_IO_TYPE m_powerOutput;

        // 复位按钮-用来清除错误使用
        INPUT_IO_TYPE m_resetBtn;

        // 是否时仿真
        std::atomic<bool> m_sim;

        // 初始化完成标识
        bool m_init;

        // 私有节点句柄
        rclcpp::Node m_priNh;

        // 订阅新的IO输入信号话题
        ros::Subscriber m_subIoNew;

        // 订阅仿真新的IO输入信号话题
        ros::Subscriber m_subIoNewSim;

        // 控制IO输出客户端
        ros::ServiceClient m_outClient;

    private:
        // hmi虚拟IO
        std::map<HmiSig, INPUT_IO_TYPE> m_hmiIo;

        // 控制hmi-io输出工具类
        COutputIoTool m_outputSimIoTool;
    };
}